package com.hdax.dm.service;

import com.hdax.dm.api.scheduler.OrderSchedulerControllerApi;
import com.hdax.dm.common.exception.DmException;
import com.hdax.dm.common.exception.order.OrderException;
import com.hdax.dm.common.exception.user.UserLoginException;
import com.hdax.dm.entity.base.Image;
import com.hdax.dm.entity.item.Item;
import com.hdax.dm.entity.order.Order;
import com.hdax.dm.entity.order.OrderLinkUser;
import com.hdax.dm.entity.scheduler.OrderScheduler;
import com.hdax.dm.entity.scheduler.SchedulerSeat;
import com.hdax.dm.entity.user.LinkUser;
import com.hdax.dm.entity.user.User;
import com.hdax.dm.feign.base.ImageFeign;
import com.hdax.dm.feign.item.ItemFeign;
import com.hdax.dm.feign.order.OrderFeign;
import com.hdax.dm.feign.scheduler.OrderSchedulerFeign;
import com.hdax.dm.feign.scheduler.SchedulerSeatFeign;
import com.hdax.dm.feign.user.LinkUserFeign;
import com.hdax.dm.util.IdWorker;
import com.hdax.dm.vo.OrderVo;
import com.hdax.dm.vo.confirmpayVo;
import com.hdax.dm.vo.queryorderlistVo;
import com.hdax.dm.vo.querypersoninfoVo;
import org.elasticsearch.search.DocValueFormat;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class OrderService {

    @Autowired
    private OrderFeign orderFeign;
    @Autowired
    private ItemFeign itemFeign;
    @Autowired
    private LinkUserFeign linkUserFeign;
    @Autowired
    private OrderSchedulerFeign orderSchedulerFeign;
    @Autowired
    private SchedulerSeatFeign schedulerSeatFeign;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private ImageFeign imageFeign;

    //添加订单和订单详情个修改座位状态
    public String saveOrder(OrderVo orderVo, HttpServletRequest request) throws DmException{

        //判断是否被锁
        while (redisTemplate.opsForValue().get("orderLock") != null){
            System.out.println("循环调用锁");
        }
        if (redisTemplate.opsForValue().get("orderLock") == null){
            //加锁
            System.out.println("加锁");
            redisTemplate.opsForValue().set("orderLock","lock");
        }

        //判断商品是否存在
        /*Item item1 = itemFeign.itemDesc(orderVo.getItemId());
        if (item1 == null){
            redisTemplate.delete("orderLock");
            throw new DmException("3001","商品不存在");
        }*/

        //invoiceType--isNeedInvoice--itemId--userId----对不上
        //获取用户id
        String token = request.getHeader("token");
        if (token == null || token.equals("")){
            throw new UserLoginException(UserLoginException.ERR_INFO.NO_LOGIN_MSG,
                    UserLoginException.ERR_INFO.NO_LOGIN_CODE);
        }
        String s = token.split(":")[1].split("-")[0];
        Order order = new Order();
        BeanUtils.copyProperties(orderVo,order);
        //订单编号,分布式项目中需要保证唯一性
        String orderNo = IdWorker.getId();

        //计算座位总价
        if (orderVo.getInvoiceHead().equals("") || orderVo.getInvoiceHead() == null){
            order.setInvoiceType(0L);
        } else {
            order.setInvoiceType(1L);
        }
        double totalAmount = 0d;
        //座位集合,回滚用
        List<SchedulerSeat> schedulerSeatList = new ArrayList<>();
        //拆分x_y
        String[] seatPositions = orderVo.getSeatPositions().split(",");
        for (int i = 0; i < seatPositions.length;i++) {
            //每一个的横纵坐标
            long x = Long.parseLong(seatPositions[i].split("_")[0]);
            long y = Long.parseLong(seatPositions[i].split("_")[1]);
            OrderScheduler orderScheduler = orderSchedulerFeign.price(x, y, orderVo.getSchedulerId());
            Double price = orderScheduler.getPrice();
            SchedulerSeat seat = new SchedulerSeat();
            totalAmount+=price;
            //判断座位状态
            if (orderScheduler.getStatus() != 1){
                redisTemplate.delete("orderLock");
                throw new OrderException(OrderException.ERR_INFO.NO_SEAT_CODE,
                        OrderException.ERR_INFO.NO_SEAT_MSG);
            }
            orderScheduler.setOrderNo("");
            orderScheduler.setUserId(null);
            orderScheduler.setStatus(1L);
            BeanUtils.copyProperties(orderScheduler,seat);
            schedulerSeatList.add(seat);
        }

        order.setOrderNo(orderNo);
        order.setUserId(Long.parseLong(s));
        order.setSchedulerId(orderVo.getSchedulerId());
        order.setItemId(orderVo.getItemId());

        Item item = itemFeign.itemDesc(order.getItemId());

        order.setItemName(item.getItemName());
        order.setOrderType(0L);
        order.setPayType(2L);
        //总票数
        order.setTotalCount(Long.valueOf(seatPositions.length));
        order.setIsNeedInvoice(orderVo.getIsNeedInvoice());
        order.setInvoiceHead(orderVo.getInvoiceHead());
        order.setInvoiceNo(orderVo.getInvoiceId() == ""?null:orderVo.getInvoiceId());
        order.setIsNeedInsurance(orderVo.getIsNeedInsurance());
        if (orderVo.getIsNeedInsurance() == 1L){
            order.setInsuranceAmount(20d);
            order.setTotalAmount(totalAmount+20d);
        } else {
            order.setTotalAmount(totalAmount);
        }
        //订单添加
        try {
            orderFeign.addOrder(order);
        } catch (Exception e){
            //事务回滚
            //删除订单
            rabbitTemplate.convertAndSend("dm_order_rollback",orderNo);
            redisTemplate.delete("orderLock");
            throw new DmException("2002","添加订单失败！");
        }

        Order order1 = orderFeign.FindByOrderId(orderNo);
        Long orderId = order1.getId();
        OrderLinkUser orderLinkUser = new OrderLinkUser();
        String[] linkIds = orderVo.getLinkIds().split(",");
        if (linkIds[0] != null && !linkIds[0].equals("0") && !linkIds[0].equals("")){
            for (int i = 0;i<seatPositions.length;i++){
                String linkId = null;
                if (linkIds[i] == null || linkIds[i].equals("")){
                    linkId = linkIds[0];
                } else {
                    linkId = linkIds[i];
                    orderLinkUser.setOrderId(orderId.toString());
                    orderLinkUser.setLinkUserId(Long.parseLong(linkId));
                    LinkUser linkUser = linkUserFeign.getById(Long.parseLong(linkId));
                    orderLinkUser.setLinkUserName(linkUser.getName());
                    for (int j = i;j <= i ;j++){
                        long x = Long.parseLong(seatPositions[j].split("_")[0]);
                        long y = Long.parseLong(seatPositions[j].split("_")[1]);
                        //修改排期座位状态为待付款
                        SchedulerSeat updateSeat = new SchedulerSeat();
                        updateSeat.setOrderNo(orderNo);
                        updateSeat.setX(x);
                        updateSeat.setY(y);
                        updateSeat.setScheduleId(orderVo.getSchedulerId());
                        updateSeat.setStatus(2L);
                        updateSeat.setUserId(Long.parseLong(s));
                        try {
                            schedulerSeatFeign.updateSeatStatus(updateSeat);
                            System.out.println("修改座位成功");
                        } catch (Exception e){
                            //事务回滚
                            //删除订单
                            rabbitTemplate.convertAndSend("dm_order_rollback",orderNo);
                            //修改座位状态
                            schedulerSeatList.forEach(schedulerSeat->{
                                rabbitTemplate.convertAndSend("dm_scheduler_seat_rollback",schedulerSeat);
                            });
                            //释放锁
                            redisTemplate.delete("orderLock");
                            throw new DmException("2003","座位抢购失败!");
                        }
                        //添加订单联系人
                        OrderScheduler orderScheduler = orderSchedulerFeign.price(x, y, orderVo.getSchedulerId());
                        orderLinkUser.setX(x);
                        orderLinkUser.setY(y);
                        orderLinkUser.setPrice(orderScheduler.getPrice());
                        try {
                            orderFeign.addOrderLink(orderLinkUser);
                        } catch (Exception e){
                            //事务回滚
                            //删除订单
                            rabbitTemplate.convertAndSend("dm_order_rollback",orderNo);
                            //修改座位状态
                            schedulerSeatList.forEach(schedulerSeat -> {
                                rabbitTemplate.convertAndSend("dm_scheduler_seat_rollback",schedulerSeat);
                            });
                            //删除订单联系人
                            rabbitTemplate.convertAndSend("dm_order_link_user_rollback",orderId);
                            //释放锁
                            redisTemplate.delete("orderLock");
                            throw new DmException("2004","添加联系人失败!");
                        }
                    }
                }
            }
        }
        //释放锁
        System.out.println("释放锁----------");
        redisTemplate.delete("orderLock");
        //设置订单15分钟过期
        redisTemplate.opsForValue().set("orderNo:"+orderNo,orderNo,15, TimeUnit.MINUTES);
        return orderNo;
    }

    public confirmpayVo confirmpay(String orderNo){
        Order order = orderFeign.FindByOrderId(orderNo);
        confirmpayVo confirmpayVo = new confirmpayVo();
        BeanUtils.copyProperties(order,confirmpayVo);
        return confirmpayVo;
    }

    public List<queryorderlistVo> queryorderlist(Map<String,Object> params){
        String keyword = params.get("keyword").toString();
        Date orderTime = null;
        Long orderTimes = Long.parseLong(params.get("orderTime").toString());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        String time = null;
        if (orderTimes == 1){
            int i = LocalDateTime.now().getYear() - 1;
            int i1 = LocalDateTime.now().getMonthValue();
            int i2 = LocalDateTime.now().getDayOfMonth();
            time = i+"-"+i1+"-"+i2;
            try {
                orderTime = format.parse(time);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        } else if (orderTimes == 2){
            c.setTime(new Date());
            c.add(Calendar.MONDAY,-3);
            Date date = c.getTime();
            time = format.format(date);
            try {
                orderTime = format.parse(time);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        Object orderType;
        Long userId = null;
        if (!params.get("orderType").equals("")){
            orderType = Long.parseLong(params.get("orderType").toString());
        } else {
            orderType = "";
        }
        if (!params.get("userId").equals("")){
            userId = Long.parseLong(params.get("userId").toString());
        }
        Object a = "";
        if (orderTime != null){
            //将date转换为localdatetime
            Instant instant = orderTime.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            a = LocalDateTime.ofInstant(instant,zoneId);
        }

        List<Order> lists = orderFeign.queryorderlist(keyword, a, orderType, userId);
        List<queryorderlistVo> vos = new ArrayList<>();
        lists.forEach(list->{
            queryorderlistVo vo = new queryorderlistVo();
            BeanUtils.copyProperties(list,vo);
            vo.setSellTime(list.getCreatedTime());
            vo.setNum(list.getTotalCount());
            vos.add(vo);
        });
        return vos;
    }

    public String deleteticketbuyer(Long linkId){
        boolean b = orderFeign.deleteticketbuyer(linkId);
        if (b){
            return "删除成功!";
        } else {
            return "删除失败!";
        }
    }

    public querypersoninfoVo querypersoninfo(Long userId){
        User user = orderFeign.querypersoninfo(userId);
        querypersoninfoVo vo = new querypersoninfoVo();
        BeanUtils.copyProperties(user,vo);
        vo.setSex(user.getSex().toString());
        vo.setInterest(user.getHobby());
        Image image = imageFeign.image(user.getId(), 0L, 0L);
        if (image != null){
            vo.setHeadUrl(image.getImgUrl()==null?"":image.getImgUrl());
        }
        return vo;
    }

    public boolean modifypersoninfo(Map<String,String> map){
        User user = new User();
        user.setId(Long.parseLong(map.get("id")));
        user.setSex(Long.parseLong(map.get("sex")));
        user.setPhone(map.get("phone"));
        user.setNickName(map.get("nickName"));
        user.setRealName(map.get("realName"));
        user.setIdCard(map.get("idCard"));
        user.setHobby(map.get("interest"));
        LocalDateTime now = LocalDateTime.now();
        //将String类型的birthday转换成localdatetime
        String time = map.get("birthday");
        String s1 = time.substring(0, 10);
        String s2 = time.substring(11, 19);
        time = s1+" "+s2;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime birthday = LocalDateTime.parse(time,dateTimeFormatter);
        user.setBirthday(birthday);
        //修改个人信息
        boolean flag1 = orderFeign.modifypersoninfo(user);

        //修改头像
        boolean flag2 = orderFeign.modifypersoninfo1(user.getId(), map.get("headUrl"));
        if (flag1 == false || flag2 == false){
            return false;
        }
        return true;
    }

}
